package com.ldn.basic.utils.tencent;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import com.ldn.basic.utils.DateUtils;
import com.ldn.basic.utils.cache.HutoolCacheUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 李大牛家的牛 (scafel@163.com) 
 * @createDate 2024/8/25 - 16:01
 * @description ...
 **/
@Slf4j
public class WechatTokenUtil {


    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 获取微信token
     * @title getAccessToken
     * @date 2024/8/25 - 16:25
     * @param appid: 小程序或公众号的appid
     * @param secret: 小程序或公众号的secret
     * @return java.lang.String
     **/
    public static String getAccessToken(String appid, String secret) throws RuntimeException {
        AccessToken token = HutoolCacheUtils.getObj("wechat_access_token_" + appid, AccessToken.class);
        log.info("微信获取token token => {}", token.toString());
        if (StrUtil.isBlank(token.getAccessToken()) || token.getExpiresIn() <= DateUtils.getCurrentS()) {
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
            String replaceUrl = url.replace("{0}", appid).replace("{1}", secret);
            String res = HttpUtil.get(replaceUrl);
            JSONObject jsonObject = JSONUtil.parseObj(res);
            log.info("微信获取token res => {}", jsonObject);
            String errcode = jsonObject.getStr("errcode");
            if (StrUtil.isBlank(errcode) || StrUtil.compare(errcode, "0", true) == 0){
                AccessToken accessToken = new AccessToken();
                accessToken.setAccessToken(jsonObject.getStr("access_token"));
                accessToken.setExpiresIn(jsonObject.getInt("expires_in") + DateUtils.getCurrentS());
                HutoolCacheUtils.set("wechat_access_token", accessToken);
                return accessToken.getAccessToken();
            }
            throw new RuntimeException(jsonObject.getStr("errmsg"));
        }
        return token.getAccessToken();
    }


    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 订单发货
     * @title orderDelivery
     * @date 2024/8/25 - 17:10
     * @param order:
     * @return boolean
     **/
    public static boolean orderDelivery(OrderDeliveryPacket order) throws RuntimeException{
        String accessToken = getAccessToken(order.getAppid(), order.getSecret());
        if (StrUtil.isBlank(accessToken)){
            throw new RuntimeException("微信令牌获取失败!");
        }
        String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken;
        JSONObject order_key = JSONUtil.createObj();
        order_key.set("out_trade_no", order.getOut_trade_no());
        order_key.set("mchid", order.getMchid());
        order_key.set("order_number_type", order.getOrder_number_type());
        JSONObject shipping = JSONUtil.createObj();
        shipping.set("item_desc", order.getItem_desc());
        List<Map<String, Object>> shipping_list = new ArrayList<>();
        shipping_list.add(shipping);
        JSONObject payer = JSONUtil.createObj();
        payer.set("openid", order.getOpenid());
        JSONObject params = JSONUtil.createObj();
        params.set("order_key", order_key);
        params.set("logistics_type", order.getLogistics_type().getCode());
        params.set("delivery_mode",order.getDelivery_mode().getCode());
        params.set("is_all_delivered", order.is_all_delivered());
        params.set("upload_time", order.getUpload_time());
        params.set("shipping_list", shipping_list);
        params.set("payer", payer);
        log.info("微信订单发货参数 params => {}", params);
        String res = HttpUtil.post(url, params.toString());
        JSONObject jsonObject = JSONUtil.parseObj(res);
        log.info("微信订单发货 res => {}", jsonObject);
        String errcode = jsonObject.getStr("errcode");
        if (StrUtil.isBlank(errcode) || StrUtil.compare(errcode, "0", true) == 0){
            return true;
        }
        throw new RuntimeException(jsonObject.getStr("errmsg"));
    }

    public static String getWxMemberPhone(String appId, String secret, String code) throws RuntimeException {
        String accessToken = getAccessToken(appId, secret);
        if (StrUtil.isBlank(accessToken)){
            throw new RuntimeException("微信令牌获取失败!");
        }
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
        JSONObject params = JSONUtil.createObj();
        params.set("code", code);
        String res = HttpUtil.post(url, params.toString());
        JSONObject jsonObject = JSONUtil.parseObj(res);
        log.info("微信获取用户手机号 res => {}", jsonObject);
        String errcode = jsonObject.getStr("errcode");
        if (StrUtil.isBlank(errcode) || StrUtil.compare(errcode, "0", true) == 0){
            JSONObject phone_info = jsonObject.getJSONObject("phone_info");
            String phoneNumber = phone_info.getStr("phoneNumber");
            if (StrUtil.isBlank(phoneNumber)) {
                throw new RuntimeException("获取用户手机号失败!手机号为空");
            }
            return phoneNumber;
        }
        throw new RuntimeException(jsonObject.getStr("errmsg"));
    }
}


class AccessToken {

    private String accessToken;
    private long expiresIn = 0;

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public long getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(long expiresIn) {
        this.expiresIn = expiresIn;
    }

    @Override
    public String toString() {
        return "AccessToken{'accessToken:'" + accessToken + ", expiresIn:" + expiresIn + '}';
    }
}